package com.pro.staffmanage.utils;

import org.springframework.security.crypto.argon2.Argon2PasswordEncoder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder;

import java.security.InvalidAlgorithmParameterException;
import java.util.*;

public class PasswordUtil {
    //  目前BCRYPT和PBKDF2所需要的东西是全部导入的, 但argon2和scrypt需要org.bouncycastle

    private static String BCRYPT_ENCODING_ID = "bcrypt";
    private static String PBKDF2_ENCODING_ID = "pbkdf2";
    private static String SCRYPT_ENCODING_ID = "scrypt";
    private static String ARGON2_ENCODING_ID = "argon2";

    private static Map<String, PasswordEncoder> encoders = new HashMap<String, PasswordEncoder>() {
        {
            put(BCRYPT_ENCODING_ID, new BCryptPasswordEncoder());
            put(PBKDF2_ENCODING_ID, new Pbkdf2PasswordEncoder());
            put(SCRYPT_ENCODING_ID, new SCryptPasswordEncoder());
            put(ARGON2_ENCODING_ID, new Argon2PasswordEncoder());
        }
    };

    private static String encodingId = BCRYPT_ENCODING_ID;

    public static String getPassword(String password, String encodingId) throws InvalidAlgorithmParameterException {
        return createDelegatingPasswordEncoder(encodingId).encode(password);
    }

    public static String getPassword(String password) {
        return createDelegatingPasswordEncoder().encode(password);
    }

    public static boolean isCipherText(String password) throws InvalidAlgorithmParameterException {
        if (password.charAt(0) == '{') {
            for (String item : PasswordUtil.encoders.keySet()) {
                if (password.contains(item)) {
                    return true;
                }
            }
            throw new InvalidAlgorithmParameterException("No encodingId!");
        }
        return false;
    }

    public static PasswordEncoder createDelegatingPasswordEncoder() {
        return new DelegatingPasswordEncoder(encodingId, encoders);
    }

    //  创建指定的Encoder
    public static PasswordEncoder createDelegatingPasswordEncoder(String encodingId) throws InvalidAlgorithmParameterException {
        if (!encoders.keySet().contains(encodingId)){
            throw new InvalidAlgorithmParameterException("No encodingId!");
        }
        return new DelegatingPasswordEncoder(encodingId, encoders);
    }

    //  选择加密算法, 可用于SecurityConfiguration(@EnableWebSecurity)中配置Bean
    public static PasswordEncoder choiceCipherStrategy(String encodingId) {
        return PasswordUtil.encoders.get(encodingId);
    }

    public List<String> getStrategy() {
        Set<String> strategy = PasswordUtil.encoders.keySet();
        return new ArrayList<>(strategy);
    }

}
